﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LumenLiquid.Debug;
using LumenLiquid.InGame;
using Microsoft.Xna.Framework.Graphics;

namespace LumenLiquid.Resources
{
    public class Effectmanager
    {
        private struct SEffect
        {
            public string Id { get; set; }
            public Effect Effect { get; set; }

            public SEffect(string id = null)
                : this()
            {
                Id = id;
            }
        }


        private Dictionary<string, List<SEffect>> _effects;

        public Effectmanager()
        {
            DebugHandler.Log("Starting effectmanager...", DebugHandler.EDebugLevel.Code);
            _effects = new Dictionary<string, List<SEffect>>();
            _effects.Add("global", new List<SEffect>());
        }

        /// <summary>
        /// Gets a model in the global group
        /// </summary>
        /// <param name="id">The id of the model to load</param>
        /// <returns>The model file</returns>
        /// <remarks>If model doesn't exist, the model will be loaded. The global group cannot be unloaded, so watch out what you put in there.</remarks>
        public Effect GetGlobalEffect(string id)
        {
            DebugHandler.Log("Getting global effect with id \"" + id + "\"");

            SEffect effect = _effects["global"].Find(m => Equals(m.Id, id));

            if (effect.Id == null)
            {
                effect.Effect = Main.Instance.Content.Load<Effect>(Path.Content.Effects + id);
                effect.Id = id;
            }

            if (effect.Effect == null)
            {
                DebugHandler.Log("Effect with id \"" + id + "\" was not found.", DebugHandler.EDebugLevel.Warning);
                return null;
            }

            _effects["global"].Add(effect);

            return effect.Effect;
        }

        /// <summary>
        /// Gets a model for the current world
        /// </summary>
        /// <param name="id">The id of the model to load</param>
        /// <returns>The model file</returns>
        /// <remarks>If model doesn't exist, the model will be loaded.</remarks>
        public Effect GetWorldEffect(string id)
        {
            DebugHandler.Log("Getting world effect with id \"" + id + "\"");

            if (!_effects.ContainsKey(MainGame.Instance.World))
                _effects.Add(MainGame.Instance.World, new List<SEffect>());

            SEffect effect = _effects[MainGame.Instance.World].Find(m => Equals(m.Id, id));

            if (effect.Id == null)
            {
                effect.Effect = Main.Instance.Content.Load<Effect>(Path.Content.WorldFolder + MainGame.Instance.World + Path.Content.MapEffects + id);
                effect.Id = id;
            }

            if (effect.Effect == null)
            {
                DebugHandler.Log("Effect with id \"" + id + "\" was not found in world \"" + MainGame.Instance.World + "\"", DebugHandler.EDebugLevel.Warning);
                return null;
            }

            _effects[MainGame.Instance.World].Add(effect);

            return effect.Effect;
        }

        /// <summary>
        /// Gets a model from a specific group
        /// </summary>
        /// <param name="id">The id of the model</param>
        /// <param name="group">The group in which the model is placed</param>
        /// <returns>The model file</returns>
        /// <remarks>If model doesn't exist, the model will be loaded.</remarks>
        public Effect GetGroupEffect(string id, string group)
        {
            DebugHandler.Log("Getting effect with id \"" + id + "\"");

            if (!_effects.ContainsKey(group))
                _effects.Add(group, new List<SEffect>());

            SEffect effect = _effects[group].Find(m => Equals(m.Id, id));

            if (effect.Id == null)
            {
                effect.Effect = Main.Instance.Content.Load<Effect>(Path.Content.Effects + id);
                effect.Id = id;
            }

            if (effect.Effect == null)
            {
                DebugHandler.Log("Effect with id \"" + id + "\" was not found.", DebugHandler.EDebugLevel.Warning);
                return null;
            }

            _effects[group].Add(effect);

            return effect.Effect;
        }

        /// <summary>
        /// Unloads a whole group or world
        /// </summary>
        /// <param name="group">The group or world to unload</param>
        /// <remarks>Group global cannot be unloaded</remarks>
        public void UnloadGroup(string group)
        {
            if (!Equals(group, "global") && group != null)
            {
                DebugHandler.Log("Unloading effect group \"" + group + "\"");
                _effects.Remove(group);
            }
        }
    }
}
